﻿using Newtonsoft.Json;
using NLog;
using NLog.Config;
using NLog.Targets.Wrappers;
using System;
using System.ComponentModel;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Tools.Client.Helper;

namespace Tools.Client
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private DispatcherTimer Timer;

        private Tools.Client.Library.Dictionary.Config Config = new Tools.Client.Library.Dictionary.Config();

        private Tools.Client.Library.Cache.Client Cache = Tools.Client.Library.Cache.Client.Instance;

        private bool _UpLock = false;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void MainWindow_Closing(object sender, CancelEventArgs e)
        {
            Tools.Client.Library.Connection.RabbitMQ.Instance.Close();
            Timer.Stop();
        }
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var target = new WpfRichTextBoxTarget
            {
                Name = "RichText",
                Layout = "[${longdate:useUTC=false}] ${message}",
                ControlName = LogRichTextBox.Name,
                FormName = GetType().Name,
                AutoScroll = true,
                MaxLines = 100000,
                UseDefaultRowColoringRules = true,
            };
            var asyncWrapper = new AsyncTargetWrapper { Name = "RichTextAsync", WrappedTarget = target };

            LogManager.Configuration.AddTarget(asyncWrapper.Name, asyncWrapper);
            LogManager.Configuration.LoggingRules.Insert(0, new LoggingRule("W", LogLevel.Info, asyncWrapper));
            LogManager.ReconfigExistingLoggers();


            LogManager.GetLogger("W").Info("欢迎使用 luffy.tools 列队落地与提交.");

            try
            {
                Library.Dictionary.MQConfig mQConfig = JsonConvert.DeserializeObject<Library.Dictionary.MQConfig>(
                                Cache.get("MQConfig")
                            );
                HostType.Text = mQConfig.HostType;
                HostName.Text = mQConfig.HostName;
                Port.Text = mQConfig.Port.ToString();
                UserName.Text = mQConfig.UserName;
                Password.Text = mQConfig.Password;
                VirtualHost.Text = mQConfig.VirtualHost;
            }
            catch (MissingFieldException)
            {
                LogManager.GetCurrentClassLogger().Warn("没有公共参数缓存！");
            }

            try
            {
                Library.Dictionary.QueueConfig DownConfig = JsonConvert.DeserializeObject<Library.Dictionary.QueueConfig>(
                        Cache.get("DownConfig")
                    );
                DownQueueName.Text = DownConfig.QueueName;
                DownExchangeName.Text = DownConfig.ExchangeName;
                DownExchangeType.Text = DownConfig.ExchangeType;
                DownDurableOpen.IsChecked = DownConfig.Durable;
                DownDurableClose.IsChecked = !DownConfig.Durable;
                DownAutoDeleteOpen.IsChecked = DownConfig.AutoDelete;
                DownAutoDeleteClose.IsChecked = !DownConfig.AutoDelete;
                DownRoutingKey.Text = DownConfig.RoutingKey;
                DownDir.Text = DownConfig.Dir;
            }
            catch (MissingFieldException)
            {
                LogManager.GetCurrentClassLogger().Warn("没有提交参数缓存！");
            }

            try
            {
                Library.Dictionary.QueueConfig UpConfig = JsonConvert.DeserializeObject<Library.Dictionary.QueueConfig>(
                        Cache.get("UpConfig")
                    );
                UpQueueName.Text = UpConfig.QueueName;
                UpExchangeName.Text = UpConfig.ExchangeName;
                UpExchangeType.Text = UpConfig.ExchangeType;
                UpDurableOpen.IsChecked = UpConfig.Durable;
                UpDurableClose.IsChecked = !UpConfig.Durable;
                UpAutoDeleteOpen.IsChecked = UpConfig.AutoDelete;
                UpAutoDeleteClose.IsChecked = !UpConfig.AutoDelete;
                UpRoutingKey.Text = UpConfig.RoutingKey;
                UpDir.Text = UpConfig.Dir;
            }
            catch (MissingFieldException)
            {
                LogManager.GetCurrentClassLogger().Warn("没有提交参数缓存！");
            }

            Timer = new DispatcherTimer();
            Timer.Interval = new TimeSpan(0, 5, 0);
            //时间间隔为一秒
            Timer.Tick += new EventHandler(Timer_Tick);
            Timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            try
            {
                if (_MQButton.IsEnabled == false && Tools.Client.Library.Connection.RabbitMQ.Instance.IsOpen() == false)
                {
                    Tools.Client.Library.Connection.RabbitMQ.Instance.ReConnection(Config.MQConfig);
                }

                if (_UpLock == false && _UpButton.IsEnabled == false)
                {
                    _ = LoopFolder();
                }

                if (_DownButton.IsEnabled == false && Tools.Client.Library.Connection.RabbitMQ.Instance.ConsumeIModelOpen() == false)
                {
                    LogManager.GetLogger("W").Info("重拉消费环境");
                    DownAction();
                }
            }
            catch (Exception Ex)
            {
                LogManager.GetCurrentClassLogger().Info("检测任务出现异常:" + Ex.Message);
                LogManager.GetCurrentClassLogger().Info("检测任务出现异常:" + Ex.StackTrace);
                LogManager.GetCurrentClassLogger().Info("检测任务出现异常:" + Ex.TargetSite);
            }

        }

        private void MQButton_Click(object sender, RoutedEventArgs e)
        {

            HiddenMQGrid();

            Config.MQConfig.HostType = HostType.Text;
            Config.MQConfig.HostName = HostName.Text;
            Config.MQConfig.UserName = UserName.Text;
            Config.MQConfig.Password = Password.Text;
            Config.MQConfig.VirtualHost = VirtualHost.Text;
            Config.MQConfig.Port = int.Parse(Port.Text);

            
            try
            {
                Tools.Client.Library.Connection.RabbitMQ.Instance.Connection(Config.MQConfig);

                Cache.set("MQConfig", JsonConvert.SerializeObject(Config.MQConfig));

                LogManager.GetLogger("W").Info("MQ连接成功");
            }
            catch(Exception ex)
            {
                LogManager.GetLogger("W").Info(ex);
                ShowMQGrid();
            }
            
        }
        
        private void ShowMQGrid()
        {
            _MQButton.IsEnabled = true;
            HostType.IsEnabled = true;
            HostName.IsEnabled = true;
            UserName.IsEnabled = true;
            Password.IsEnabled = true;
            VirtualHost.IsEnabled = true;
            Port.IsEnabled = true;
        }
        private void HiddenMQGrid()
        {
            _MQButton.IsEnabled = false;
            HostType.IsEnabled = false;
            HostName.IsEnabled = false;
            UserName.IsEnabled = false;
            Password.IsEnabled = false;
            VirtualHost.IsEnabled = false;
            Port.IsEnabled = false;
        }

        private void DownButton_Click(object sender, RoutedEventArgs e)
        {
            HiddenDownGrid();
            try
            {
                Config.DownConfig.QueueName = DownQueueName.Text;
                Config.DownConfig.ExchangeName = DownExchangeName.Text;
                Config.DownConfig.ExchangeType = DownExchangeType.Text;
                Config.DownConfig.RoutingKey = DownRoutingKey.Text;
                Config.DownConfig.Dir = DownDir.Text;
                Config.DownConfig.Durable = DownDurableOpen.IsChecked == true ? true : false;
                Config.DownConfig.AutoDelete = DownAutoDeleteOpen.IsChecked == true ? true : false;

                DownAction();

                Cache.set("DownConfig", JsonConvert.SerializeObject(Config.DownConfig));

                LogManager.GetLogger("W").Info("消费队列成功");
            }
            catch
            {
                ShowDownGrid();
            }          
        }

        private void DownAction()
        {
            Action<string> _Callback = (string msg) =>
            {
                Message message;
                try
                {
                    message = JsonConvert.DeserializeAnonymousType(msg, new Message());
                }
                catch
                {
                    throw new Exception("解析失败！");
                }

                string FileName = Config.DownConfig.Dir + "/" + message.name + ".xml";
                try
                {
                    byte[] myByte = System.Text.Encoding.UTF8.GetBytes(message.message);
                    FileStream fsWrite = new FileStream(FileName, FileMode.Create);
                    fsWrite.Write(myByte, 0, myByte.Length);
                    fsWrite.Close();
                    LogManager.GetCurrentClassLogger().Info("拉取文件成功：" + FileName);
                }
                catch
                {
                    throw new Exception("文件保存失败: " + FileName);
                }

            };

            Action<string> _ErrorCallback = (string message) =>
            {
                LogManager.GetCurrentClassLogger().Error(message);
            };

            Tools.Client.Library.Connection.RabbitMQ.Instance.Consume(Config.DownConfig, _Callback, _ErrorCallback);
        }

        private void HiddenDownGrid()
        {
            _DownButton.IsEnabled = false;
            DownDir.IsEnabled = false;
            DownAutoDeleteOpen.IsEnabled = false;
            DownAutoDeleteClose.IsEnabled = false;
            DownRoutingKey.IsEnabled = false;
            DownDurableClose.IsEnabled = false;
            DownDurableOpen.IsEnabled = false;
            DownExchangeType.IsEnabled = false;
            DownExchangeName.IsEnabled = false;
            DownQueueName.IsEnabled = false;
            _DownChooseFolderBrowser.IsEnabled = false;
        }

        private void ShowDownGrid()
        {
            _DownButton.IsEnabled = true;
            DownDir.IsEnabled = true;
            DownAutoDeleteOpen.IsEnabled = true;
            DownAutoDeleteClose.IsEnabled = true;
            DownRoutingKey.IsEnabled = true;
            DownDurableClose.IsEnabled = true;
            DownDurableOpen.IsEnabled = true;
            DownExchangeType.IsEnabled = true;
            DownExchangeName.IsEnabled = true;
            DownQueueName.IsEnabled = true;
            _DownChooseFolderBrowser.IsEnabled = true;
        }

        private void _DownChooseFolderBrowser_Click(object sender, RoutedEventArgs e)
        {
            DownDir.Text = Tools.Client.Library.ChooseFolderBrowser.Instance.run(DownDir.Text);
        }

        private void _UpChooseFolderBrowser_Click(object sender, RoutedEventArgs e)
        {
            UpDir.Text = Tools.Client.Library.ChooseFolderBrowser.Instance.run(UpDir.Text);
        }

        private void UpButton_Click(object sender, RoutedEventArgs e)
        {
            HiddenUpGrid();
            try
            {
                Config.UpConfig.QueueName = UpQueueName.Text;
                Config.UpConfig.ExchangeName = UpExchangeName.Text;
                Config.UpConfig.ExchangeType = UpExchangeType.Text;
                Config.UpConfig.RoutingKey = UpRoutingKey.Text;
                Config.UpConfig.Dir = UpDir.Text;
                Config.UpConfig.Durable = UpDurableOpen.IsChecked == true ? true : false;
                Config.UpConfig.AutoDelete = UpAutoDeleteOpen.IsChecked == true ? true : false;

                if (!Directory.Exists(Config.UpConfig.Dir))
                {
                    throw new Exception("目录不存在");
                }

                _ = LoopFolder();

                Cache.set("UpConfig", JsonConvert.SerializeObject(Config.UpConfig));
                LogManager.GetLogger("W").Info("生产队列成功");
            }
            catch(Exception ex)
            {
                LogManager.GetLogger("W").Error("生产队列失败:" + ex.Message);
                ShowUpGrid();
            }
        }

        async Task LoopFolder()
        {
            await Task.Run(() => {
                _UpLock = true;
                var BackDir = Config.UpConfig.Dir + "_back/" + DateTime.Now.ToString("yyyy-MM-dd") + "/";
                if (!Directory.Exists(BackDir))
                {
                    Directory.CreateDirectory(BackDir);
                }
                foreach (string file in Directory.GetFileSystemEntries(Config.UpConfig.Dir))
                {
                    if (File.Exists(file))
                    {
                        try
                        {
       
                            Tools.Client.Library.Connection.RabbitMQ.Instance.Product(Config.UpConfig, File.ReadAllText(file));

                            var backfile = BackDir + System.Guid.NewGuid().ToString("N");
                            File.Move(file, backfile);

                            LogManager.GetCurrentClassLogger().Info("回执备份成功:" + file);
                        }
                        catch(Exception ex)
                        {
                            LogManager.GetLogger("W").Error(ex.Message);
                        }                            
                    }
                }
                _UpLock = false;
            });
        }

        private void HiddenUpGrid()
        {
            _UpButton.IsEnabled = false;
            UpDir.IsEnabled = false;
            UpAutoDeleteOpen.IsEnabled = false;
            UpAutoDeleteClose.IsEnabled = false;
            UpRoutingKey.IsEnabled = false;
            UpDurableClose.IsEnabled = false;
            UpDurableOpen.IsEnabled = false;
            UpExchangeType.IsEnabled = false;
            UpExchangeName.IsEnabled = false;
            UpQueueName.IsEnabled = false;
            _UpChooseFolderBrowser.IsEnabled = false;
        }

        private void ShowUpGrid()
        {
            _UpButton.IsEnabled = true;
            UpDir.IsEnabled = true;
            UpAutoDeleteOpen.IsEnabled = true;
            UpAutoDeleteClose.IsEnabled = true;
            UpRoutingKey.IsEnabled = true;
            UpDurableClose.IsEnabled = true;
            UpDurableOpen.IsEnabled = true;
            UpExchangeType.IsEnabled = true;
            UpExchangeName.IsEnabled = true;
            UpQueueName.IsEnabled = true;
            _UpChooseFolderBrowser.IsEnabled = true;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            throw new Exception("这个异常没有捕捉");
        }
    }

    public class Message
    {
        /// <summary>
        /// 内容
        /// </summary>
        public string message { set; get; }
        /// <summary>
        /// 文件名
        /// </summary>
        public string name { set; get; }
    }
}
